import java.util.concurrent.*;
import java.nio.channels.*;
import java.net.*;
import java.util.*;
import java.io.*;


class ProvisionApplication implements IChannelHandler, Runnable
{

   ExecutorService threadPool = null;
   Selector requestSelector = null;


   public ProvisionApplication() throws IOException
   {
      threadPool = Executors.newFixedThreadPool(100);
      requestSelector = Selector.open();

   }

   public static void main(String[] args)
   {
      if (args.length != 1)
      {
         System.out.println("Need port number");
         return;
      }

      Server server = new Server(Integer.parseInt(args[0]));
      ProvisionApplication app = null;

      try
      {
         app = new ProvisionApplication();
      }
      catch(IOException e)
      {
         System.out.println(e.toString());
         return;
      }


      Thread selectThread = new Thread(app);


      server.serve(app);



   }

   public void clientConnected(SocketChannel channel)
   {
      try
      {
         channel.configureBlocking(false);
         channel.register(requestSelector, SelectionKey.OP_WRITE);
      }
      catch(IOException e)
      {
         try
         {
            channel.close();
         }
         catch(IOException ioEx)
         {
         }
      }

   }

   public void run()
   {
      try
      {

         while (requestSelector.select() > 0)
         {
            Set acceptedKeys = requestSelector.selectedKeys();
            Iterator i = acceptedKeys.iterator();
            while (i.hasNext())
            {
               SelectionKey key = (SelectionKey)i.next();
               threadPool.execute(new ServiceTask((SocketChannel)key.channel()));
               i.remove();
            }
         }
      }
      catch (IOException e)
      {
         try
         {
            requestSelector.close();
         }
         catch(IOException e2)
         {
         }

      }
   }

}
